// OpentTxl-C Version 11 rule table
// J.R. Cordy, Jan 2023

// Copyright 2023, James R. Cordy and others

// Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
// and associated documentation files (the “Software”), to deal in the Software without restriction, 
// including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all copies 
// or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 
// AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// The TXL Rule Table
// The TXL rule compiler stores the compiled rules and functions of the TXL program in this table,
// organized into separate stores for rule parts (constructors, deconstructors, etc.) and
// rule local variables in order to avoid artificial limits on any particular rule. 

// v11.3    Added multiple skipping criteria for both patterns and deconstructors

// Rule local variables, including formal parameters
struct ruleLocalT {
    tokenT              name;
    tokenT              typename_;
    tokenT              basetypename;
    unsigned short      partof;
    unsigned short      refs;
    treePT              lastref;
    bool                global, changed;
};

typedef int ruleLocalsBaseT;        // 0 .. maxTotalRuleLocals

struct ruleLocalsT {
    ruleLocalsBaseT     localsBase;
    unsigned short      nformals, nprelocals, nlocals;
};

// Rule parts
enum rulePartKindT {
    rulePart_construct, rulePart_deconstruct, rulePart_cond, rulePart_import, rulePart_export, rulePart_assert, rulePart_none
};

typedef unsigned short ruleLocalRefT;       // 0 .. maxLocalVars

struct rulePartT {
    enum rulePartKindT  kind;
    tokenT              name;
    ruleLocalRefT       nameRef;
    ruleLocalRefT       globalRef;
    tokenT              target;
    tokenT              skipName;
    tokenT              skipName2;
    tokenT              skipName3;
    treePT              replacementTP;
    treePT              patternTP;
    bool                starred, negated, anded, skipRepeat;
};

typedef int rulePartsBaseT;
struct  rulePartsT {
    rulePartsBaseT      partsBase;
    unsigned short      nparts;         // 0 .. maxParts
};

// Rule calls
typedef int ruleCallsBaseT;
struct  ruleCallsT {
    ruleCallsBaseT      callsBase;
    unsigned short      ncalls;
};

enum ruleKindT {
    ruleKind_rule, ruleKind_function, ruleKind_onepass, ruleKind_predefined
};

struct  ruleT {
    tokenT              name;
    struct ruleLocalsT  localVars;
    struct ruleCallsT   calledRules;
    tokenT              target;
    tokenT              skipName;
    tokenT              skipName2;
    tokenT              skipName3;
    struct rulePartsT   prePattern;
    treePT              patternTP;
    struct rulePartsT   postPattern;
    treePT              replacementTP;
    bool                defined, called, starred, isCondition, skipRepeat;
    enum ruleKindT      kind;
};

// Predefined global vars

#define TXLargsG        1
#define TXLprogramG     2
#define TXLinputG       3
#define TXLexitcodeG    4

#define numGlobalVars   4

// Predefined rules

#define addR            1
#define subtractR       2
#define multiplyR       3
#define divideR         4
#define substringR      5
#define lengthR         6
#define greaterR        7
#define greaterEqualR   8
#define lessR           9
#define lessEqualR      10
#define equalR          11
#define notEqualR       12
#define spliceR         13
#define listSpliceR     14
#define extractR        15
#define shallowextractR 16
#define substituteR     17
#define newidR          18
#define underscoreR     19
#define messageR        20
#define printR          21
#define printattrR      22
#define debugR          23
#define breakpointR     24
#define quoteR          25
#define unparseR        26
#define unquoteR        27
#define parseR          28
#define reparseR        29
#define readR           30
#define writeR          31
#define getR            32
#define getpR           33
#define putR            34
#define putpR           35
#define indexR          36
#define grepR           37
#define repeatlengthR   38
#define selectR         39
#define tailR           40
#define headR           41
#define globalR         42
#define quitR           43
#define fgetR           44
#define fputR           45
#define fputpR          46
#define fopenR          47
#define fcloseR         48
#define pragmaR         49
#define divR            50
#define remR            51
#define systemR         52
#define pipeR           53
#define tolowerR        54
#define toupperR        55
#define typeofR         56
#define istypeR         57
#define roundR          58
#define truncR          59
#define getsR           60
#define fgetsR          61
#define putsR           62
#define fputsR          63
#define faccessR        64
#define nPredefinedRules 64

// The main rule of the transformation
extern int mainRule;

// The rule table - 1-origin [1 .. maxRules]
extern array (struct ruleT, rule_rules);
extern int rule_nRules;

// The rule local variables table - 1-origin [1 .. maxTotalRuleLocals]
extern array (struct ruleLocalT, rule_ruleLocals);
extern int rule_ruleFormalCount;
extern int rule_ruleLocalCount; 
extern int maxTotalRuleParameters;  
extern int maxTotalRuleLocals;

// The rule parts table - 1-origin [1 .. maxTotalRuleParts]
extern array (struct rulePartT, rule_ruleParts);
extern int rule_rulePartCount;
extern int maxTotalRuleParts;

// The rule calls table - 1-origin [1 .. maxTotalRuleCalls]
// Used only by the rule compiler, to optimize tree sharing and avoid copying of trees
extern array (unsigned short, rule_ruleCalls);
extern int rule_ruleCallCount;
extern int maxTotalRuleCalls;

#ifdef TXLMAIN
// Initialization
extern void rule (void);
#endif

#ifdef COMPILER
// Used only in comprul.c rule compilation
extern int rule_enterRule (const tokenT ruleName);
extern void rule_cloneRule (const int newIndex, const int oldIndex);
extern int rule_enterLocalVar (const string context, struct ruleLocalsT *ruleLocalVars, const tokenT varName, const tokenT varType);
extern void rule_cloneLocalVar (const int newLocalIndex, const int oldLocalIndex);
extern int rule_lookupLocalVar (const string context, const struct ruleLocalsT *ruleLocalVars, const tokenT varName);
extern int rule_findLocalVar (const string context, const struct ruleLocalsT *ruleLocalVars, const tokenT varName);
extern void rule_enterRuleCall (const string context, const int callingRuleIndex, const int calledRuleIndex);
extern void rule_setCalled (const int ruleIndex, const bool setting);
extern void rule_setDefined (const int ruleIndex, const bool setting);
extern void rule_setIsCondition (const int ruleIndex, const bool setting);
extern void rule_setKind (const int ruleIndex, const enum ruleKindT kind);
extern void rule_setPattern (const int ruleIndex, const treePT patternTP);
extern void rule_setReplacement (const int ruleIndex, const treePT replacementTP);
extern void rule_setSkipRepeat (const int ruleIndex, const bool setting);
extern void rule_setStarred (const int ruleIndex, const bool setting);
extern void rule_setTarget (const int ruleIndex, const tokenT typeName);
extern void rule_setLocalsBase (const int ruleIndex, const int localsBase);
extern void rule_setNFormals (const int ruleIndex, const int nformals);
extern void rule_setNPreLocals (const int ruleIndex, const int npreruleLocal);
extern void rule_setNLocals (const int ruleIndex, const int nruleLocal);
extern void rule_setCallsBase (const int ruleIndex, const int callsBase);
extern void rule_setNCalls (const int ruleIndex, const int ncalls);
extern void rule_setPrePatternPartsBase (const int ruleIndex, const int partsBase);
extern void rule_setPrePatternNParts (const int ruleIndex, const int nparts);
extern void rule_setPostPatternPartsBase (const int ruleIndex, const int partsBase);
extern void rule_setPostPatternNParts (const int ruleIndex, const int nparts);
extern void rule_setSkipName (const int ruleIndex, const tokenT name);
extern void rule_incLocalCount (const int increment);
extern void rule_incFormalCount (const int increment);
extern void rule_incPartCount (const int increment);
extern void rule_incLocalRefs (const int ruleLocalIndex, const int increment);
extern void rule_setLocalChanged (const int ruleLocalIndex, const bool setting);
extern void rule_setLocalGlobal (const int ruleLocalIndex, const bool setting);
extern void rule_setLocalLastRef (const int ruleLocalIndex, const treePT lastref);
extern void rule_setLocalName (const int ruleLocalIndex, const tokenT name);
extern void rule_setLocalPartOf (const int ruleLocalIndex, const int nameRef);
extern void rule_setLocalRefs (const int ruleLocalIndex, const int refs);
extern void rule_setLocalType (const int ruleLocalIndex, const tokenT typeName);
extern void rule_setPartKind (const rulePartsBaseT partIndex, const enum rulePartKindT kind);
extern void rule_setPartName (const rulePartsBaseT partIndex, const tokenT name);
extern void rule_setPartNameRef (const rulePartsBaseT partIndex, const int nameRef);
extern void rule_setPartTarget (const rulePartsBaseT partIndex, const tokenT typeName);
extern void rule_setPartPattern (const rulePartsBaseT partIndex, const treePT patternTP);
extern void rule_setPartReplacement (const rulePartsBaseT partIndex, const treePT replacementTP);
extern void rule_setPartNegated (const rulePartsBaseT partIndex, const bool setting);
extern void rule_setPartAnded (const rulePartsBaseT partIndex, const bool setting);
extern void rule_setPartStarred (const rulePartsBaseT partIndex, const bool setting);
extern void rule_setPartSkipName (const rulePartsBaseT partIndex, const tokenT name);
extern void rule_setPartSkipRepeat (const rulePartsBaseT partIndex, const bool setting);
extern void rule_setPartGlobalRef (const rulePartsBaseT partIndex, const treePT ref);
extern void rule_checkPredefinedFunctionScopeAndParameters (const string context, const int ruleIndex, 
        const tokenT scopetype, const tokenT p1type, const tokenT p2type);
#endif

// Used in parse.c parser as well as in compurul.c rule compiler  
extern void rule_unenterLocalVar (const string context, struct ruleLocalsT *ruleLocalVars, const tokenT varName);
